﻿using System;
using Qiniu.Conf;
using Qiniu.IO;
using Qiniu.RS;
using System.Threading.Tasks;
using System.Net.Http;
using ModernHttpClient;
using System.Net;
using Newtonsoft.Json;

namespace Moven.Data
{
	public class CloudKeyValueStorage: IKeyValueStorage
	{
		IOClient _client = new IOClient();
		const string BucketName = "moven",
			BucketDomain = "ofu0tpicp.bkt.clouddn.com",
			HttpNotFoundJson = "{\"error\":\"Document not found\"}",
			EncryptedAccessKey = "VclQeSS/b6/2YUmz9oMwUUQtQT80vgm5Ylt+xT6J57D1oBDtH7xmIt7Ut3EfHqBuo60dJMptnabwdlyL2mYbskCvPvP0vj382QOHKXx0Dbs7ujqKqRp5PSELOkhrPEOA2odKyn+J3IDqc+AaiAlQg5gqe2CaP9GWA4CPlyvLVg8=",
			EncryptedSecretKey = "fumq+e/64ZdW69Btii0Ez7I4LUYczauO2PFJkKWsKGMBK4eU+owGDpQLWxe9t3B7yxLQIa0NeUR/YmPy/rz44FXsi+qNlAAt7zgDxcLb2a9DMydL4jxeLqb6hwgWcTQOZiZfvlFbAt26JFwI1N53eMpr2Bp8SzIOMM168DXPpec=",
			Password = "godess2016@";

		static CloudKeyValueStorage()
		{
			Config.ACCESS_KEY =  EncryptedAccessKey.Decrypt(Password); 
			Config.SECRET_KEY = EncryptedSecretKey.Decrypt(Password);
		}

		public async Task<T> GetValueAsync<T>(string key)
		{
			key = key.AddJsonExtension();
			var baseUrl = GetPolicy.MakeBaseUrl(BucketDomain, key);
			var privateUrl = GetPolicy.MakeRequest(baseUrl);
			using (var httpClient = new HttpClient(new NativeMessageHandler())
			{
				Timeout = TimeSpan.FromSeconds(10)
			})
			{
				var response = await httpClient.GetAsync(privateUrl);
				if (response.StatusCode != HttpStatusCode.OK)
				{
					return default(T);
				}
				var json = await response.Content.ReadAsStringAsync();
				if (json.IsNullOrEmpty() || json.Trim(' ', '\n', '\t') == HttpNotFoundJson)
				{
					return default(T);
				}

				return JsonConvert.DeserializeObject<T>(json);
			}
		}


		public T GetValueFromPredefinedData<T>(string key)
		{
			throw new NotImplementedException();
		}

		public async Task SetValueAsync<T>(string key, T value)
		{
			key = key.AddJsonExtension();
			var json = JsonConvert.SerializeObject(value);

			using (var stream = json.GenerateStream())
			{
				var putPolicy = new PutPolicy($"{BucketName}:{key}");
				var uploadToken = putPolicy.Token();
				var putRet = await _client.PutAsync(uploadToken, key, stream, new PutExtra());
				Console.WriteLine("The returned key from Qiniu is " + putRet.key);
			}
		}
	}
}
